/*
* Copyright 2015 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.uberfire.server.locale;
import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Locale;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import org.apache.commons.lang3.LocaleUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
/**
* Serializes and adds the GWT locale meta tag in the
* application's host page. This is useful in case the
* host page is a simple html file.
*/
public class GWTLocaleHeaderFilter implements Filter {
@Override
public void init(final FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
@Override
public void doFilter(final ServletRequest request,
final ServletResponse response,
final FilterChain chain) throws IOException, ServletException {
final CharResponseWrapper wrappedResponse = getWrapper((HttpServletResponse) response);
chain.doFilter(request,
wrappedResponse);
final String output;
final Locale locale = getLocale(request);
final String injectedScript = "<meta name=\"gwt:property\" content=\"locale=" + locale.toString() + "\">";
final Document document = Jsoup.parse(wrappedResponse.toString());
document.head().append(injectedScript);
output = document.html();
final byte[] outputBytes = output.getBytes("UTF-8");
response.setContentLength(outputBytes.length);
response.getWriter().print(output);
}
protected CharResponseWrapper getWrapper(final HttpServletResponse response) {
return new CharResponseWrapper(response);
}
private Locale getLocale(final ServletRequest request) {
Locale locale = request.getLocale();
final String paramLocale = request.getParameter("locale");
if (paramLocale == null || paramLocale.isEmpty()) {
return locale;
}
try {
locale = LocaleUtils.toLocale(paramLocale);
} catch (Exception e) {
//Swallow. Locale is initially set to ServletRequest locale
}
return locale;
}
static class CharResponseWrapper extends HttpServletResponseWrapper {
protected CharArrayWriter charWriter = new CharArrayWriter();
protected ServletOutputStream outputStream = new ServletOutputStream() {
@Override
public boolean isReady() {
return true;
}
@Override
public void setWriteListener(WriteListener writeListener) {
// TODO how to treat the listener?
}
@Override
public void write(int b) throws IOException {
charWriter.write(b);
}
};
protected PrintWriter writer = new PrintWriter(charWriter);
public CharResponseWrapper(final HttpServletResponse response) {
super(response);
}
@Override
public ServletOutputStream getOutputStream() throws IOException {
return outputStream;
}
@Override
public PrintWriter getWriter() throws IOException {
return writer;
}
@Override
public void flushBuffer() throws IOException {
// Don't remove this override!
// When intercepting static content, WAS 8.5.5.5 prematurely calls this
// method to flush the output stream before we can calculate the content
// length (see above).
}
@Override
public String toString() {
return charWriter.toString();
}
}
}